package cn.gov.pbc.gd.credit.provider.api.log.impl;

import java.io.Serializable;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import com.liu.jbase.PageListVo;
import com.liu.jbase.service.mongo.IMongoClient;

import cn.gov.pbc.gd.credit.api.log.ILogLoginApi;
import cn.gov.pbc.gd.credit.vo.log.LogLoginVo;

@Service
public class LogLoginApiImpl implements ILogLoginApi {

	@Autowired
	private IMongoClient<LogLoginVo> mongoClient;

	@Override
	public void insert(LogLoginVo entity) throws Exception {
		mongoClient.insert(entity);
	}

	@Override
	public void updateById(Serializable id, String key, String value) throws Exception {

		mongoClient.updateById(id, key, value, LogLoginVo.class);
	}

	@Override
	public void update(LogLoginVo vo) throws Exception {
		mongoClient.update(vo);
	}

	@Override
	public void update(LogLoginVo vo, String key, String value) throws Exception {

		Query query = new Query();

		mongoClient.update(query, key, value, LogLoginVo.class);

	}

	@Override
	public void deleteById(Serializable id) throws Exception {
		mongoClient.deleteById(id, LogLoginVo.class);

	}

	@Override
	public void deleteByQuery(LogLoginVo vo) throws Exception {

		Query query = new Query();

		mongoClient.deleteByQuery(query, LogLoginVo.class);

	}

	@Override
	public LogLoginVo getOneById(Serializable id) throws Exception {

		return mongoClient.getOneById(id, LogLoginVo.class);
	}

	@Override
	public LogLoginVo getOne(LogLoginVo vo) throws Exception {

		Query query = new Query();
		
		if (vo != null) {
			if(vo.getQueryFlag() != null && vo.getQueryFlag() == 1){
				
				query.addCriteria(Criteria.where("userId").is(vo.getUserId()));
				query.with(new Sort(new Order(Direction.DESC,"createTime"))); 
				PageListVo<LogLoginVo> page = new PageListVo<>();
				page.setCurrPage(1);
				page.setPageSize(1);
				page = mongoClient.getPage(query, page, LogLoginVo.class);
				if (page != null && page.getRows() != null && page.getRows().size() > 0) {
					return page.getRows().get(0);
				} 
				
				return null;
			}
		}
		
		return mongoClient.getOne(query, LogLoginVo.class);
	}

	@Override
	public List<LogLoginVo> getAll(Class<LogLoginVo> entity) throws Exception {
		return mongoClient.getAll(entity);
	}

	@Override
	public List<LogLoginVo> getAll(LogLoginVo vo) throws Exception {

		Query query = new Query();

		return mongoClient.getAll(query, LogLoginVo.class);
	}

	@Override
	public long getCount(LogLoginVo vo) throws Exception {

		Query query = new Query();

		return mongoClient.getCount(query, LogLoginVo.class);
	}

	@Override
	public PageListVo<LogLoginVo> getPage(LogLoginVo vo, PageListVo<LogLoginVo> page) throws Exception {

		setTimeFromString(vo);

		Query query = new Query();

		if (vo.getLoginResult() != null && vo.getLoginResult() != 0) {// 1. 行为状态

			query.addCriteria(Criteria.where("loginResult").is(vo.getLoginResult()));
		}

		if (vo.getAuthType() != null && vo.getAuthType() != 0) {// 2.认证方式
																// Integer

			query.addCriteria(Criteria.where("authType").is(vo.getAuthType()));
		}

		if (vo.getCorpName() != null && vo.getCorpName() != "" && vo.getCorpName().length() > 0) { // 3.支行名称

			Pattern pattern = Pattern.compile("^.*" + vo.getCorpName() + ".*$", Pattern.CASE_INSENSITIVE);

			query.addCriteria(Criteria.where("corpName").regex(pattern));

		}

		if (vo.getBeginTime() != null && vo.getEndTime() != null) {// 4.开始时间,和结束时间，不能分开写

			query.addCriteria(Criteria.where("loginTime").gte(vo.getBeginTime()).lte(vo.getEndTime()));
		}
		if (vo.getBeginTime() != null && vo.getEndTime() == null) {// 4.开始时间 // gte是大于等于

			query.addCriteria(Criteria.where("loginTime").gte(vo.getBeginTime()));
		}

		if (vo.getBeginTime() == null && vo.getEndTime() != null) {// 5.结束时间，lte小于等于

			query.addCriteria(Criteria.where("loginTime").lte(vo.getEndTime()));
		}

		if (vo.getAccount() != null && vo.getAccount() != "" && vo.getAccount().length() > 0) {// 6.账号

			Pattern pattern = Pattern.compile("^.*" + vo.getAccount() + ".*$", Pattern.CASE_INSENSITIVE);

			query.addCriteria(Criteria.where("account").regex(pattern));
		}

		if (vo.getLoginIp() != null && vo.getLoginIp() != "" && vo.getLoginIp().length() > 0) {

			Pattern pattern = Pattern.compile("^.*" + vo.getLoginIp() + ".*$", Pattern.CASE_INSENSITIVE);

			query.addCriteria(Criteria.where("loginIp").regex(pattern));
		}
		query.with(new Sort(new Order(Direction.DESC,"createTime"))); 
		return mongoClient.getPage(query, page, LogLoginVo.class);
	}

	// 将LogLoginVo中的endTimeString/beginTimeString转换格式并赋值给endTime/beginTime
	private void setTimeFromString(LogLoginVo vo) {

		if (vo.getEndTimeString() != null && vo.getEndTimeString() != "" && vo.getEndTimeString().length() > 0) {
			vo.setEndTime(getDateFromLocalDateTime(getLocalDateTimeForString(vo.getEndTimeString()).plusDays(1)));
		}

		// 结束时间，应该是下一天的零点
		if (vo.getBeginTimeString() != null && vo.getBeginTimeString() != "" && vo.getBeginTimeString().length() > 0) {
			vo.setBeginTime(getDateFromLocalDateTime(getLocalDateTimeForString(vo.getBeginTimeString())));
		}

	}

	/**
	 * 
	 * @param strDate
	 *            8位数字（字符串格式）
	 * @return 将8位字符串数字转换为日期格式，如：20121212-->2012.12.12。
	 *         如果输入的字符串格式不正确或者为null,输出日期为2017.1.1
	 */
	private LocalDateTime getLocalDateTimeForString(String strDate) {

		Pattern p = Pattern.compile("[^0-9]");

		Matcher numMat = p.matcher(strDate);

		String strDateNum = numMat.replaceAll("").trim();// 将strDate变为纯数字组合

		if (strDateNum == null || strDateNum == "" || strDateNum.length() == 0) {

			return null; // 如果传入为空，则返回空值

		}

		LocalDateTime localDateTime = null;

		Pattern pattern = Pattern.compile("[0-9]{8}"); // 正则，8位纯数字

		Matcher isNum8 = pattern.matcher(strDateNum);

		if (isNum8.matches()) { // 如果字符串为，8位纯数字，则添加时分秒，并转换为LocalDateTime格式的时间

			strDateNum += "000000";

			localDateTime = LocalDateTime.parse(strDateNum, DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));

		} else {

			localDateTime = LocalDateTime.of(2017, 1, 1, 0, 0); // 字符串不是8位数字，则设置时间为2017.1.1

		}

		return localDateTime;
	}

	private Date getDateFromLocalDateTime(LocalDateTime localDateTime) {
		// 将LocalDateTime转换为Date格式输出
		ZoneId zone = ZoneId.systemDefault();

		Instant instant = localDateTime.atZone(zone).toInstant();

		Date date = Date.from(instant);

		return date;
	}

}
